-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Directly run system given world #2427
Conversation
fn run(&mut self, world: &mut World); | ||
|
||
/// Runs the exclusive system directly on the world, initializing the world correctly | ||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For both methods, it may be useful to describe how to persistently store and then access a system, rather than initializing it every frame.
This reduces work by enabling query caching and also allows Local
resources to persist correctly.
I'm just not sure that the API docs are the right place to put that; it feels like content that might be better suited to the book.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I suppose that the way to do this is to probably store the system, run .initialize
once, and then call the old .run()
manually.
The new method is much more convenient, but will probably perform worse for repeated invocations.
Hmm. Maybe we also demonstrate how to store and run a stage in the same section of the book?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced that this API is more useful than the existing APIs
I think I'd prefer to just change the run
method to initialise self
; although this API could be useful for exclusive systems since they might already get called using the 'run' method.
Really, we just need to be much more explicit about System
's safety conditions
/// Runs the exclusive system in the world. | ||
/// | ||
/// Use [`run_direct`] instead if you are manually running a system outside of a schedule | ||
|
||
fn run(&mut self, world: &mut World); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this imply that run has an additional safety requirement that self
is initialised for this world?
If that is so, then it should be unsafe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not unsafe in the Rust sense; it merely panics with an opaque error message.
The problem with this is that you lose all the nice caching, and have to repeat the initialization work repeatedly. This is much less of an issue in one-off systems that are being run than it is in schedules though.
The aim of this is actually to make working with exclusive world access easier, rather than compete directly with the way that other |
But I mean that the actual body of this function seems to be: fn apply_direct(world){
self.init(world);
self.run(world);
} |
Immediately applying buffers is the other very useful trick for ordinary non-exclusive systems, which lets you bypass thinking about "have my commands applied yet". This is largely a convenience method, but I think that it does a good job helping reduce boilerplate and mental overhead for basic uses by hiding some of the largely internal implementation details and just doing what end users would like to do when writing custom commands or using ordinary system syntax within larger exclusive systems.
|
Credit to @mockersf for teaching me how to do this
error[E0599]: no method named `run_direct` found for struct `ExclusiveSystemFn` in the current scope
Closing this out as I don't think it's immediately the way forward. We can easily reimplement this if needed. |
Objective
Systems are an ergonomic and expressive API for performing well-encapsulated complex logic.
However, you could not easily use them while working directly with &mut World for custom commands, exclusive systems, writing tests or bare-bones bevy_ecs usage.
Solution
Adds a System::run_direct method, which immediately executes a single system on a particular world and then flushes any Commands (or similar system parameters).
The equivalent run_direct method is also created for exclusive systems.
This is also very useful for users who may want to construct their own game loop in part or whole, sacrificing parallelism for simplicity and control.
Notes
Successor to #2417; exposing an API that dodges the ownership issues created there. Closely related to #2234.